package de.unikoblenz.west.csxpoi;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/**
 * Parses the XML response from a POI REST request.
 */
public class PoiResponseHandler extends DefaultHandler {

	/**
	 * the requested POI
	 */
	private PoiWrapper mPoi = null;

	/**
	 * the current category of the POI
	 */
	private CategoryWrapper mCurrentCategory = null;

	/**
	 * the characters of the current tag
	 */
	private String mCurrentCharacters = "";

	/**
	 * the constant for the poi tag
	 */
	private static final String POI_TAG = "poi";

	/**
	 * the constant for the status attribute
	 */
	private static final String STATUS_ATTRIBUTE = "status";

	/**
	 * the constant for the id attribute
	 */
	private static final String ID_TAG = "id";

	/**
	 * the constant for the name tag
	 */
	private static final String NAME_TAG = "name";

	/**
	 * the constant for the lat tag
	 */
	private static final String LAT_TAG = "lat";

	/**
	 * the constant for the long tag
	 */
	private static final String LONG_TAG = "long";

	/**
	 * the constant for the alt tag
	 */
	private static final String ALT_TAG = "alt";

	/**
	 * the constant for the start date tag
	 */
	private static final String START_DATE_TAG = "start";

	/**
	 * the constant for the end date tag
	 */
	private static final String END_DATE_TAG = "end";

	/**
	 * the constant for the category tag
	 */
	private static final String CATEGORY_TAG = "category";

	/**
	 * the constant for the id attribute
	 */
	private static final String ID_ATTRIBUTE = "id";

	/**
	 * Handles opening tags.
	 */
	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		if (localName.equals(POI_TAG)) {
			if (attributes.getValue(STATUS_ATTRIBUTE) != null
					&& attributes.getValue(STATUS_ATTRIBUTE).equals("success")) {
				mPoi = new PoiWrapper();
			}
		} else if (localName.equals(CATEGORY_TAG)) {
			mCurrentCategory = new CategoryWrapper();
			mCurrentCategory.setUri(attributes.getValue(ID_ATTRIBUTE));
		}
	}

	/**
	 * Handles closing tags.
	 */
	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {

		if (mPoi != null) {
			if (localName.equals(CATEGORY_TAG)) {
				mPoi.addCategory(mCurrentCategory);
				mCurrentCategory = null;
			} else if (localName.equals(ID_TAG)) {
				mPoi.setUri(mCurrentCharacters);
			} else if (localName.equals(NAME_TAG)) {
				if (mCurrentCategory != null) {
					mCurrentCategory.setName(mCurrentCharacters);
				} else {
					mPoi.setName(mCurrentCharacters);
				}
			} else if (localName.equals(LAT_TAG)) {
				try {
					mPoi.setLatitude(Double.valueOf(mCurrentCharacters));
				} catch (NumberFormatException e) {
					mPoi = null;
				}
			} else if (localName.equals(LONG_TAG)) {
				try {
					mPoi.setLongitude(Double.valueOf(mCurrentCharacters));
				} catch (NumberFormatException e) {
					mPoi = null;
				}
			} else if (localName.equals(ALT_TAG)) {
				try {
					mPoi.setAltitude(Double.valueOf(mCurrentCharacters));
				} catch (NumberFormatException e) {
					mPoi = null;
				}
			} else if (localName.equals(START_DATE_TAG)) {
				mPoi.setStartDate(mCurrentCharacters);
			} else if (localName.equals(END_DATE_TAG)) {
				mPoi.setEndDate(mCurrentCharacters);
			}
		}
	}

	/**
	 * Handles characters between tags.
	 */
	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		mCurrentCharacters = new String(ch, start, length);
	}

	/**
	 * Gets the requested POI.
	 * 
	 * @return the requested POI
	 */
	public PoiWrapper getPoi() {
		return mPoi;
	}
}
